#pragma once

#include <algorithm/analytical_model/algorithm/cuda/inter_op/Data.h>

#include <memory>
#include <vector>

namespace solar::cuda
{
    class RectangleHeliostat;
}

namespace solar::cuda::inter_op
{
    class RectangleGrid;

    class RectangleHeliostat
    {
        public:
            RectangleHeliostat();
            void setNormalAndRotate(const Float3& focus_center, const Float3& sunray_dir) const;
            void getSubHeliostatVertices(std::vector<Float3>&) const;
            void setPosition(const Float3& pos) const;
            [[nodiscard]] auto getPosition() const -> Float3;
            void setSize(const Float3& size) const;
            [[nodiscard]] auto getSize() const -> Float3;
            [[nodiscard]] auto getNormal() const -> Float3;
            [[nodiscard]] auto getVertices() const -> std::vector<Float3>;
            [[nodiscard]] auto getImagePlaneAxis() const -> std::tuple<Float3, Float3, Float3>;
            [[nodiscard]] auto getFocusCenter() const -> Float3;
            [[nodiscard]] auto getGap() const -> Float2;
            void setGap(const Float2& gap) const;
            [[nodiscard]] auto getRowAndColumn() const -> Int2;
            void setRowAndColumn(const Int2 row_col) const;
            [[nodiscard]] auto getBelongingGridId() const -> int;
            void setBelongingGridId(int grid_id) const;
            [[nodiscard]] auto getPtr() const -> solar::cuda::RectangleHeliostat*;
            friend class RectangleGrid;

        private:
            std::shared_ptr<solar::cuda::RectangleHeliostat> delegate_ptr_;
    };
} // namespace solar::cuda::inter_op
